#include "ring_buffer.h"
#include <pthread.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <time.h>

#define TEST_BUFFER_SIZE   (100 * 1024)  // 4KB测试缓冲区
#define WRITE_THREAD_COUNT 10          // 3个写入线程
#define TEST_DURATION_SEC  600          // 测试持续时间10秒
#define MAX_WRITE_SIZE     1024         // 每次最大写入量
#define MAX_READ_SIZE      1024         // 每次最大读取量

static ring_buffer_t rb;
static uint8_t buffer[TEST_BUFFER_SIZE];
static volatile bool test_running = true;
static volatile bool read_running = true;
static pthread_mutex_t mutex; 

FILE* wfile = NULL;
FILE* rfile = NULL;

// 写入线程函数
void* writer_thread(void* arg)
{
    uint32_t thread_id = (uint32_t)(uintptr_t)arg;
    uint32_t total_written = 0;
    uint32_t write_count = 0;
    uint32_t fail_count = 0;
    uint32_t full_count = 0;
    uint32_t total_count = 0;
    int    available = 0;
    uint32_t  no_space = 0;
    
    printf("Writer thread %d started\n", thread_id);
    
    while (test_running) {
        // 生成随机测试数据
        uint32_t to_write = (rand() % MAX_WRITE_SIZE) + 100 ;
        //uint32_t to_write = MAX_WRITE_SIZE;
        uint8_t test_data[to_write];
        memset(test_data, 0, sizeof(test_data));
        for (int i = 0; i < to_write; i++) {
            test_data[i]  = 'A' + (rand() % 26);
        }
        pthread_mutex_lock(&mutex);  
        available = ring_buffer_available(&rb);

         if (available < to_write)
         {
            //printf("no space! available:%d, to_write:%d", available, to_write);
            no_space++;
            pthread_mutex_unlock(&mutex); 
            continue;
         }

        // 写入数据
        int32_t written = ring_buffer_write(&rb, test_data, to_write);
        if (written > 0) {
            total_written += written;

            {   
                int wlen  = 0;    
                wlen = fwrite(test_data, 1, written, wfile);
                if ( wlen != written)
                {
                    printf("write error!!");
                }
            }
            write_count++;
        } else if (written == RB_FULL) {
            // 缓冲区满或空间不足是正常现象
            full_count++;
            //usleep(1000); // 等待1ms
        } else {
            fail_count++;
            printf("Writer %d error: %d\n", thread_id, written);
        }
        pthread_mutex_unlock(&mutex);       
        total_count++;
        usleep(1000);
    }
    
    printf("Writer %d stats: total=%u, total_count=%u, count=%u, fails=%u, full_count=%u, no_space=%u\n", 
          thread_id, total_written, total_count, write_count, fail_count, full_count, no_space);
    return NULL;
}

// 读取线程函数
void* reader_thread(void* arg)
{
    uint32_t total_read = 0;
    uint32_t read_count = 0;
    uint32_t fail_count = 0;
    uint32_t empty_count = 0;
    uint32_t total_count = 0;
    
    printf("Reader thread started\n");
    
    while (read_running) {
        // 准备读取缓冲区
        //uint32_t to_read = rand() % MAX_READ_SIZE + 1;
        uint32_t to_read = MAX_READ_SIZE;
        uint8_t read_buf[to_read];
      
        memset(read_buf, 0, sizeof(read_buf));
        // 读取数据
        int32_t read = ring_buffer_read(&rb, read_buf, to_read);
        if (read > 0) {
            total_read += read;
            {
                int w_len =0;

                w_len = fwrite(read_buf, 1, read, rfile);
                if (w_len != read)
                {
                    printf("write r.txt error!!");
                }
            }
            read_count++;
        } else if (read == RB_EMPTY) {
            // 缓冲区空或数据不足是正常现象
            empty_count++;
            usleep(10); // 等待1ms
        } else {
            fail_count++;
            printf("Reader error: %d\n", read);
        }
        
        total_count++;
        usleep(1000); 
    }
    
    printf("Reader stats: total=%u, total_count=%u, count=%u, fails=%u, empty_count=%u\n", 
          total_read, total_count, read_count, fail_count, empty_count);
    return NULL;
}

// 压力测试启动函数
int main()
{
    pthread_t writer_threads[WRITE_THREAD_COUNT];
    pthread_t reader_th;
    int result;
    int times = 0;
    
    pthread_mutex_init(&mutex, NULL);

    wfile = fopen("w.txt", "a");
    if (NULL == wfile)
    {
        printf("w.txt open fail!");
        return -1;
    }

    rfile = fopen("r.txt", "a");
    if (NULL == rfile)
    {
        printf("r.txt open fail!");
        return -1;
    }

    // 初始化随机数种子
    srand(time(NULL));
    
    // 初始化环形缓冲区
    result = ring_buffer_init(&rb, buffer, TEST_BUFFER_SIZE);
    if (result != RB_OK) {
        printf("Ring buffer init failed: %d\n", result);
        return -1;
    }
    
    printf("Starting ringbuffer pressure test (duration: %d seconds)\n", TEST_DURATION_SEC);
    
    // 创建写入线程
    for (int i = 0; i < WRITE_THREAD_COUNT; i++) {
        if (pthread_create(&writer_threads[i], NULL, writer_thread, (void*)(uintptr_t)i) != 0) {
            perror("Failed to create writer thread");
            return -1;
        }
    }
    
    // 创建读取线程
    if (pthread_create(&reader_th, NULL, reader_thread, NULL) != 0) {
        perror("Failed to create reader thread");
        return -1;
    }
    
    usleep(1000);
    printf("\n\n");
    
    // 运行测试
    while(times < TEST_DURATION_SEC)
    {
        printf("current time: %d\n", ++times);
        sleep(1);
    }

    printf("\n\n");
    
    // 停止测试
    test_running = false;
    usleep(100000); // 给线程100ms时间退出
    
    // 等待线程结束
    for (int i = 0; i < WRITE_THREAD_COUNT; i++) {
        pthread_join(writer_threads[i], NULL);
    }
    usleep(10000);
    read_running = false;
    pthread_join(reader_th, NULL);
    
    ring_buffer_deinit(&rb);
    printf("Pressure test completed\n");
    fclose(wfile);
    fclose(rfile);
    
    return 0;
}